import { CylinderGeometry, Mesh, MeshBasicMaterial,Quaternion, Scene, Vector3 } from "../libs/three137/three.module.js";
import { cylinderIntersectsSphere , sphereIntersectsCylinder} from "../libs/Collisions.js";
const {PI,ceil} = Math 

class BulletHandler { 
    constructor (game){ 
        this.game = game ;
        this.scene  = game.scene ;
        const geometry = new CylinderGeometry(0.01,.01,.08) // 圆柱
        geometry.rotateX(PI/ 2) ;
        geometry.rotateY(PI/2) ;
        const material = new MeshBasicMaterial() ;

        this.bullet = new Mesh( geometry, material) ;
        this.bullets =[] ;
        this.npcs = this.game.npcHandler.npcs 

        this.user = this.game.user ;
        this.forward = new Vector3(0,0,-1) ;
        this.xAixs = new Vector3(1,0,0) ;
        this.tmpVec3 =new Vector3() ;
        this.tepQuat = new Quaternion()
    }

    createBullet(pos = new Vector3(), quat = new Quaternion() , user =false){
        const bullet  = this.bullet.clone()  ;
        bullet.position.copy(pos) ;
        bullet.quaternion.copy(quat) ;
        bullet.userData.targetType = user? 1: 2 ;
        bullet.userData.distance =0 ;
        this.scene.add(bullet) ;
        this.bullets.push(bullet) ;
        console.count('造子弹')

    }

    update(dt){ 
        this.bullets.forEach((bullet)=> {
            let hit  = false  ;
            const p1 = bullet.position.clone() ; // 移动前的位置
            let target  ;
            const dist  = dt *15  ;// 按 60fps 算  15 就是 。25s  250ms
            bullet.translateX(dist)

            const p2 = bullet.position.clone();// 移动后的位置
            bullet.position.copy(p1) //  再回到原来的位置

            const iteration = ceil(dist / .5) ;// 。5ms检测一次

            const p = this.tmpVec3 ;
            for(let i = 1;  i <=iteration; i++){ 
                p.lerpVectors(p1,p2, i / iteration); // 这样就是线性插值了
                if(bullet.userData.targetType === 1){  // npc射击
                    const p2 = this.user.position.clone() ;
                    p2.y+=1.2 ;
                    hit  = sphereIntersectsCylinder(p.x,p.y,p.z,.01, p2.x, p2.y, p2.z, 2.4,.4) ;
                    if(hit) target = this.user ;
                }else{ // 玩家射击 
                    this.npcs.some((npc)=> { 
                        if(!npc.dead){ 
                            const p2 = npc.object.position.clone();
                            p2.y+=1.5 ; // 这应该是枪的高度  人物模型的基点都在脚下
                            //             球的坐标和半径  xyz r      圆柱的坐标, x y z  高度 h 半径 r
                            hit = sphereIntersectsCylinder(p.x,p.y,p.z,.01  ,p2.x,p2.y, p2.z, 3, .5) ;
                            if(hit ){ 
                                console.log('hit');
                                target =npc ;
                                return true }

                        }
                    })
                    // 外循环也可以停了
                    if(hit )break ;
                }

            }
            // bug在这 ，下面的判断应该在循环体外
                if(hit){
                    target.action= 'shot';
                    bullet.userData.remove =true ;

                }else { 
                    bullet.translateX(dist) ;
                    bullet.userData.distance+-dist ;
                    bullet.userData.remove = bullet.userData.distance>50 // 射程50米 
                }
          
        })

        let found = false  ;
        do{ 
            let remove ;
            found = this.bullets.some((bullet, ind) => { 
                if(bullet.userData.remove){ 
                    remove =ind ;
                    return true
                }
            })
            if(found){ 
                this.scene.remove(this.bullets[remove])
                this.bullets.splice(remove, 1) ;
            }
        }while(found)

    }
}

export {BulletHandler}